package com.ews.onlineexchange.model.approved;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;

import com.ews.onlineexchange.model.DataEntity;
import com.ews.onlineexchange.model.ServiceSupplier;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class AbstractMemo extends DataEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	protected ServiceSupplier		serviceSupplier;
	protected ApprovedMatter		approvedMatter;
	protected String				desc;
	protected List<Evidence>		evidences = new ArrayList<>();
	
	protected Date 					occurrenceTime;
	protected Integer				year;
	protected Integer				month;

	@ManyToOne
	@NotNull
	public ServiceSupplier getServiceSupplier() {
		return serviceSupplier;
	}

	public void setServiceSupplier(ServiceSupplier serviceSupplier) {
		this.serviceSupplier = serviceSupplier;
	}

	@ManyToOne
	@NotNull
	public ApprovedMatter getApprovedMatter() {
		return approvedMatter;
	}

	public void setApprovedMatter(ApprovedMatter approvedMatter) {
		this.approvedMatter = approvedMatter;
	}

	@NotNull
	@Length(max = 4000)
	@Column(name = "description")
	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	@OneToMany(cascade = CascadeType.ALL)
	public List<Evidence> getEvidences() {
		return evidences;
	}

	public void setEvidences(List<Evidence> evidences) {
		this.evidences = evidences;
	}

	@NotNull
	@Temporal(TemporalType.DATE)
	public Date getOccurrenceTime() {
		return occurrenceTime;
	}

	public void setOccurrenceTime(Date occurrenceTime) {
		this.occurrenceTime = occurrenceTime;
	}

	@NotNull
	public Integer getYear() {
		return year;
	}

	public void setYear(Integer year) {
		this.year = year;
	}

	@NotNull
	public Integer getMonth() {
		return month;
	}

	public void setMonth(Integer month) {
		this.month = month;
	}
	
	@PrePersist
	@PreUpdate
	private void preSaveOrUpdate() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getOccurrenceTime());
		this.setYear(cal.get(Calendar.YEAR));
		this.setMonth(cal.get(Calendar.MONTH) + 1);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((approvedMatter == null) ? 0 : approvedMatter.hashCode());
		result = prime * result + ((desc == null) ? 0 : desc.hashCode());
		result = prime * result + ((evidences == null) ? 0 : evidences.hashCode());
		result = prime * result + ((month == null) ? 0 : month.hashCode());
		result = prime * result + ((occurrenceTime == null) ? 0 : occurrenceTime.hashCode());
		result = prime * result + ((serviceSupplier == null) ? 0 : serviceSupplier.hashCode());
		result = prime * result + ((year == null) ? 0 : year.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		AbstractMemo other = (AbstractMemo) obj;
		if (approvedMatter == null) {
			if (other.approvedMatter != null)
				return false;
		} else if (!approvedMatter.equals(other.approvedMatter))
			return false;
		if (desc == null) {
			if (other.desc != null)
				return false;
		} else if (!desc.equals(other.desc))
			return false;
		if (evidences == null) {
			if (other.evidences != null)
				return false;
		} else if (!evidences.equals(other.evidences))
			return false;
		if (month == null) {
			if (other.month != null)
				return false;
		} else if (!month.equals(other.month))
			return false;
		if (occurrenceTime == null) {
			if (other.occurrenceTime != null)
				return false;
		} else if (!occurrenceTime.equals(other.occurrenceTime))
			return false;
		if (serviceSupplier == null) {
			if (other.serviceSupplier != null)
				return false;
		} else if (!serviceSupplier.equals(other.serviceSupplier))
			return false;
		if (year == null) {
			if (other.year != null)
				return false;
		} else if (!year.equals(other.year))
			return false;
		return true;
	}
}
